查看原文
其他

物联网MQTT—发布消息

刘尧 果果小师弟 2022-07-15

点击上方“果果小师弟”,选择“置顶/星标公众号

干货福利,第一时间送达!

发布消息的单词为publish。PUBLISH 控制报文是指从客户端向服务端或者服务端向客户端传输一个应用消息。我们这里的Qos等级为:00

一、发布消息

1.服务端向客户端传输一个应用消息

1.1固定报头

1.2.可变报头

发布消息中的可变报头不包含报文标识符,只包含主题名Topic Name。主题名(Topic Name)用于识别有效载荷数据应该被发布到哪一个信息通道。名 必须是 PUBLISH 报文可变报头的第一个字段。只有当 QoS 等级是 1 或 2 时,报文标识符(Packet Identifier)字段才能出现在 PUBLISH 报文中。我们这里设置的 QoS 等级为0,所以报文标识符不会出现在 PUBLISH 报文中。

主题名:/sys/a10zwkUxQUS/LY-1/thing/service/property/set

相应的16进制:

  • 2F 73 79 73 2F 61 31 30 7A 77 6B 55 78 51 55 53 2F 4C 59 2D 31 2F 74 68 69 6E 67 2F 73 65 72 76 69 63 65 2F 70 72 6F 70 65 72 74 79 2F 73 65 74  共48个字节(0x30)
    也就是
    00 30 2F 73 79 73 2F 61 31 30 7A 77 6B 55 78 51 55 53 2F 4C 59 2D 31 2F 74 68 69 6E 67 2F 73 65 72 76 69 63 65 2F 70 72 6F 70 65 72 74 79 2F 73 65 74

1.固定报头为:30 ??
2.可变报头为:
00 30 2F 73 79 73 2F 61 31 30 7A 77 6B 55 78 51 55 53 2F 4C 59 2D 31 2F 74 68 69 6E 67 2F 73 65 72 76 69 63 65 2F 70 72 6F 70 65 72 74 79 2F 73 65 74
最终为:

  • 30 ?? 00 30 2F 73 79 73 2F 61 31 30 7A 77 6B 55 78 51 55 53 2F 4C 59 2D 31 2F 74 68 69 6E 67 2F 73 65 72 76 69 63 65 2F 70 72 6F 70 65 72 74 79 2F 73 65 74

1.3.有效载荷

有效载荷包含将被发布的应用消息。数据的内容和格式是应用特定的。有效载荷的长度这样计算:用固定报头中的剩余长度字段的值减去可变报头的长度。包含零长度有效载荷的 PUBLISH 报文是合法的。


有效载荷包含将被发布的应用消息。数据的内容和格式是应用特定的—JSON。这个JSON的内容就是服务端要发送给客户端的数据。
现在就需要得到有效载荷:有效载荷我们通过服务端下发给客户端,操作如下:

  • 30 97 01 00 30 2F 73 79 73 2F 61 31 30 7A 77 6B 55 78 51 55 53 2F 4C 59 2D 31 2F 74 68 69 6E 67 2F 73 65 72 76 69 63 65 2F 70 72 6F 70 65 72 74 79 2F 73 65 74 7B 22 6D 65 74 68 6F 64 22 3A 22 74 68 69 6E 67 2E 73 65 72 76 69 63 65 2E 70 72 6F 70 65 72 74 79 2E 73 65 74 22 2C 22 69 64 22 3A 22 36 35 38 32 31 33 31 39 39 22 2C 22 70 61 72 61 6D 73 22 3A 7B 22 50 6F 77 65 72 53 77 69 74 63 68 22 3A 30 7D 2C 22 76 65 72 73 69 6F 6E 22 3A 22 31 2E 30 2E 30 22 7D

两个对比:

  • 30  ?? 00 30 2F 73 79 73 2F 61 31 30 7A 77 6B 55 78 51 55 53 2F 4C 59 2D 31 2F 74 68 69 6E 67 2F 73 65 72 76 69 63 65 2F 70 72 6F 70 65 72 74 79 2F 73 65 74  

  • 30  97 01 00 30 2F 73 79 73 2F 61 31 30 7A 77 6B 55 78 51 55 53 2F 4C 59 2D 31 2F 74 68 69 6E 67 2F 73 65 72 76 69 63 65 2F 70 72 6F 70 65 72 74 79 2F 73 65 74 7B 22 6D 65 74 68 6F 64 22 3A 22 74 68 69 6E 67 2E 73 65 72 76 69 63 65 2E 70 72 6F 70 65 72 74 79 2E 73 65 74 22 2C 22 69 64 22 3A 22 36 35 38 32 31 33 31 39 39 22 2C 22 70 61 72 61 6D 73 22 3A 7B 22 50 6F 77 65 72 53 77 69 74 63 68 22 3A 30 7D 2C 22 76 65 72 73 69 6F 6E 22 3A 22 31 2E 30 2E 30 22 7D

解释:

1.4.JSON

JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。JSON是指JavaScript对象表示法(JavaScrip ObjectNotation)

{
    "firstName":"John"
}
{ } : 大括号表示对象
" " : 双引号表示属性或者值
"firstName" :表示属性
"John" : 表示属性的具体信息
如:"temp":"10℃"

下面表示有四个键:

{
    "method":"thing.service.property.set",
    "id":"658213199",
    "params":{"PowerSwitch":0},
    "version":"1.0.0"
}

是不是很熟悉,就是上面发布消息的有效载荷。

2.客户端发送到服务端传输一个应用消息

2.1固定报头

2.2.可变报头

发布消息中的可变报头不包含报文标识符,只包含主题名Topic Name。主题名(Topic Name)用于识别有效载荷数据应该被发布到哪一个信息通道。名 必须是 PUBLISH 报文可变报头的第一个字段。只有当 QoS 等级是 1 或 2 时,报文标识符(Packet Identifier)字段才能出现在 PUBLISH 报文中。我们这里设置的 QoS 等级为0,所以报文标识符不会出现在 PUBLISH 报文中。

主题名:/sys/a10zwkUxQUS/LY-1/thing/event/property/post

相应的16进制:

  • 2F 73 79 73 2F 61 31 30 7A 77 6B 55 78 51 55 53 2F 4C 59 2D 31 2F 74 68 69 6E 67 2F 65 76 65 6E 74 2F 70 72 6F 70 65 72 74 79 2F 70 6F 73 74   共47个字节(0x2F)
    也就是00 2F 2F 73 79 73 2F 61 31 30 7A 77 6B 55 78 51 55 53 2F 4C 59 2D 31 2F 74 68 69 6E 67 2F 65 76 65 6E 74 2F 70 72 6F 70 65 72 74 79 2F 70 6F 73 74

1.固定报头为:30 ??
2.可变报头为:00 27 2F 73 79 73 2F 61 31 30 7A 77 6B 55 78 51 55 53 2F 4C 59 2D 31 2F 74 68 69 6E 67 2F 65 76 65 6E 74 2F 70 72 6F 70 65 72 74 79 2F 70 6F 73 74

最终为:

  • 30 ?? 00 2F 2F 73 79 73 2F 61 31 30 7A 77 6B 55 78 51 55 53 2F 4C 59 2D 31 2F 74 68 69 6E 67 2F 65 76 65 6E 74 2F 70 72 6F 70 65 72 74 79 2F 70 6F 73 74

2.3.有效载荷

有效载荷包含将被发布的应用消息。数据的内容和格式是应用特定的。有效载荷的长度这样计算:用固定报头中的剩余长度字段的值减去可变报头的长度。包含零长度有效载荷的 PUBLISH 报文是合法的。


有效载荷包含将被发布的应用消息。数据的内容和格式是应用特定的—JSON。这个JSON的内容就是服务端要发送给客户端的数据。
现在就需要得到有效载荷:上面我们已经知道了服务端(阿里云服务器)下发到客户端(网络调试助手)的数据内容是:
{
    "method":"thing.service.property.set",
    "id":"658213199",
    "params":{"PowerSwitch":0},
    "version":"1.0.0"
}

那么同理我们可以得到客户端(网络调试助手)上发到服务端(阿里云服务器)的数据内容也就是有效载荷。

{
    "method":"thing.event.property.post",
    "id":"00000001",
    "params":{"PowerSwitch":1,"CurrentHumidity":30,"CurrentTemperature":11.1},
    "version":"1.0.0"
}

服务端(阿里云服务器)下发到客户端(网络调试助手)中的数据内容中method是thing.service.property.set。那么客户端(网络调试助手)上发到服务端(阿里云服务器)中的数据内容method是thing.event.property.post。注意区别,id可以修改只要是8位数即可。params中的数据也可以随便改,因为我的设备有温湿度和开关,所以就加上了温湿度的信息。
把他转换为16进制也就得到有效载荷的报文:

7B 22 6D 65 74 68 6F 64 22 3A 22 74 68 69 6E 67 2E 65 76 
65 6E 74 2E 70 72 6F 70 65 72 74 79 2E 70 6F 73 74 22 2C 
22 69 64 22 3A 22 30 30 30 30 30 30 30 31 22 2C 22 70 61 
72 61 6D 73 22 3A 7B 22 50 6F 77 65 72 53 77 69 74 63 68 
22 3A 31 2C 22 43 75 72 72 65 6E 74 48 75 6D 69 64 69 74 
79 22 3A 33 30 2C 22 43 75 72 72 65 6E 74 54 65 6D 70 65 
72 61 74 75 72 65 22 3A 31 31 2E 31 7D 2C 22 76 65 72 73
 69 6F 6E 22 3A 22 31 2E 30 2E 30 22 7D 
 一共146个字节


最终可得发布消息报文为:
  • 30  C3 01 00 2F  2F 73 79 73 2F 61 31 30 7A 77 6B 55 78 51 55 53 2F 4C 59 2D 31 2F 74 68 69 6E 67 2F 65 76 65 6E 74 2F 70 72 6F 70 65 72 74 79 2F 70 6F 73 747B 22 6D 65 74 68 6F 64 22 3A 22 74 68 69 6E 67 2E 65 76 65 6E 74 2E 70 72 6F 70 65 72 74 79 2E 70 6F 73 74 22 2C 22 69 64 22 3A 22 30 30 30 30 30 30 30 31 22 2C 22 70 61 72 61 6D 73 22 3A 7B 22 50 6F 77 65 72 53 77 69 74 63 68 22 3A 31 2C 22 43 75 72 72 65 6E 74 48 75 6D 69 64 69 74 79 22 3A 33 30 2C 22 43 75 72 72 65 6E 74 54 65 6D 70 65 72 61 74 75 72 65 22 3A 31 31 2E 31 7D 2C 22 76 65 72 73  69 6F 6E 22 3A 22 31 2E 30 2E 30 22 7D

现在我们通过网络调试助手来向阿里云服务端发布消息
 1.第一步向服务端发送connect报文确认是否连接成功。


 2.在确认连接成功之后,向服务器发送发布消息报文
  • 30  C3 01 00 2F  2F 73 79 73 2F 61 31 30 7A 77 6B 55 78 51 55 53 2F 4C 59 2D 31 2F 74 68 69 6E 67 2F 65 76 65 6E 74 2F 70 72 6F 70 65 72 74 79 2F 70 6F 73 747B 22 6D 65 74 68 6F 64 22 3A 22 74 68 69 6E 67 2E 65 76 65 6E 74 2E 70 72 6F 70 65 72 74 79 2E 70 6F 73 74 22 2C 22 69 64 22 3A 22 30 30 30 30 30 30 30 31 22 2C 22 70 61 72 61 6D 73 22 3A 7B 22 50 6F 77 65 72 53 77 69 74 63 68 22 3A 31 2C 22 43 75 72 72 65 6E 74 48 75 6D 69 64 69 74 79 22 3A 33 30 2C 22 43 75 72 72 65 6E 74 54 65 6D 70 65 72 61 74 75 72 65 22 3A 31 31 2E 31 7D 2C 22 76 65 72 73  69 6F 6E 22 3A 22 31 2E 30 2E 30 22 7D  



3.发布消息报文发送成功之后,调试助手的接收端不会显示任何数据且调试助手不会自动断开,同时在你的阿里云服务器的设备中可以看到刚刚上报给服务器的温湿度还有电源开关的数据。当然如果你发送的报文有错误的话,你的网络调试助手会自动断开而且设备端也不会显示任何数据。可以看到下图的温湿度信息显示正常,说明发布消息成功。



4.这样我们就通过网络调试助手上我们的阿里云服务器发送数据成功了。假如你有单片机和esp8266的话,就可以代替调试助手向服务器发送数据了。哈哈,是不是很奇妙啊!

3.剩余长度

上面我们说剩余长度为195,转换成16进制就是C3 01。这好像跟我们用计算器算的不同啊!


这是MQTT中文手册中对剩余长度的描述和表示方法。
  • 1、剩余长度字段使用一个变长度编码方案,对小于128的值它使用单字节编码

  • 2、低7位有效位用于编码数据,最高有效位用于指示是否有更多的字节。剩余长度字段最大4个字节。

显然195是大于128的是不能用单字节表示的。


二、发布确认

  上面我们说到我们发送发布消息的报文之后。网络调试助手没有返回信息,是因为我们的Qos等级设置的是00,而手册上说publish报文是对QoS 1等级的publish报文的响应,所以我们收不到是正常的。



END


推荐好文  点击蓝色字体即可跳转

【收藏】烂大街的ESP82666该咋玩

【物连网】IOT你真的懂吗?

【MQTT】Connect控制报文

【MQTT】订阅报文

【典藏】基于SYN7318智能家居语音识别系统的设计

【鸡汤】如何做一名合格的研究生?


如果觉得文章对你有帮助,欢迎转发、留言、点赞、分享给你的朋友,感谢您的支持!

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存